/*
 *    Copyright (c) 2018-2025, cloud All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: cloud
 */
package com.fuyao.cloud.asset.sau.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.asset.cti.service.AssetCtiService;
import com.fuyao.cloud.asset.entity.AssetCti;
import com.fuyao.cloud.asset.entity.AssetSau;
import com.fuyao.cloud.asset.sau.mapper.AssetSauMapper;
import com.fuyao.cloud.asset.sau.service.AssetSauService;
import com.fuyao.cloud.asset.vo.SauExcelVO;
import com.fuyao.cloud.asset.vo.SauImportVO;
import com.fuyao.cloud.asset.vo.SauPageVO;
import com.fuyao.cloud.common.core.model.BaseEntity;
import com.fuyao.cloud.common.core.util.R;
import com.fuyao.cloud.common.data.datascope.DataScope;
import com.fuyao.cloud.common.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 标准资产型号
 *
 * @author liyue
 * @date 2021-11-17 17:29:51
 */
@Service
@AllArgsConstructor
public class AssetSauServiceImpl extends ServiceImpl<AssetSauMapper, AssetSau> implements AssetSauService {

    private final AssetCtiService fyAssetCtiService;


    @Override
    public boolean save(AssetSau entity) {
        setFieldValue(entity);
        return super.save(entity);
    }

    @Override
    public boolean updateById(AssetSau entity) {
        setFieldValue(entity);
        return super.updateById(entity);
    }

    @Override
    public List listSau(QueryWrapper<AssetSau> query) {
        List<AssetSau> sauList = this.baseMapper.selectListByScope(query, new DataScope());
        return sauList.stream().map(entity -> {
            SauExcelVO exportVO = new SauExcelVO();
            BeanUtils.copyProperties(entity, exportVO);
            return exportVO;
        }).collect(Collectors.toList());
    }

    @Override
    public R importSau(List<SauImportVO> excelVOList, BindingResult bindingResult) {
        // 通用校验获取失败的数据
        List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
        // 个性化校验逻辑
        List<AssetCti> ctiList = this.fyAssetCtiService.list();

        if (CollUtil.isEmpty(excelVOList)) {
            assert errorMessageList != null;
            errorMessageList.add(new ErrorMessage("无数据导入"));
            return R.failed(errorMessageList);
        }
        // 执行数据插入操作 组装 FyRoomRegional
        for (int i = 0; i < excelVOList.size(); i++) {
            SauImportVO excel = excelVOList.get(i);
            Set<String> errorMsg = new HashSet<>();

            if (StrUtil.isEmpty(excel.getName())) {
                errorMsg.add("  资产名称为空， ");
            }
            if (StrUtil.isEmpty(excel.getBarcode())) {
                errorMsg.add(" 条形码为空， ");
            }
            if (StrUtil.isEmpty(excel.getUnit())) {
                errorMsg.add(" 计量单位为空， ");
            }
            if (StrUtil.isEmpty(excel.getModel())) {
                errorMsg.add(" 规则型号为空， ");
            }
            // 拷贝属性
            AssetSau sau = new AssetSau();
            BeanUtils.copyProperties(excel, sau);

            // 处理资产分类
            if (StrUtil.isNotEmpty(excel.getClassifiedCode())) {
                Optional<AssetCti> parentOptional = ctiList.stream().filter(item -> item.getCode().equals(excel.getClassifiedCode())).findFirst();
                if (parentOptional.isPresent()) {
                    AssetCti parentCti = parentOptional.get();
                    sau.setCtiId(parentCti.getId());
                    sau.setClassified(parentCti.getName());
                    sau.setClassifiedCode(parentCti.getFullcode());
                }
            } else {
                errorMsg.add(String.format(" 资产类型不存在%s:。 ", excel.getClassifiedCode()));
            }

            // 数据合法情况
            if (CollUtil.isEmpty(errorMsg)) {
                this.save(sau);
            } else {
                // 数据不合法情况
                errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
            }
        }
        if (CollUtil.isNotEmpty(errorMessageList)) {
            return R.failed(errorMessageList);
        }
        return R.ok();
    }

    @Override
    public List<Tree<Long>> selectTree(QueryWrapper<AssetSau> query) {
        // 查询型号标准信息
        List<AssetSau> sauList = this.baseMapper.selectList(query);
        List<AssetCti> ctiList = fyAssetCtiService.list();

        // 权限内房屋信息
        List<TreeNode<Long>> collect = sauList.stream()
                .sorted(Comparator.comparing(AssetSau::getId)).map(sau -> {
                    TreeNode<Long> treeNode = new TreeNode();
                    treeNode.setId(sau.getId());
                    treeNode.setParentId(0L);
                    treeNode.setName(sau.getName());
                    treeNode.setWeight(120);
                    // 有权限不返回标识
                    Map<String, Object> extra = new HashMap<>(12);
                    extra.put("barcode", sau.getBarcode());
                    extra.put("model", sau.getModel());
                    extra.put("unit", sau.getUnit());

                    // 填充分类信息
                    Optional<AssetCti> ctiOptional = ctiList.stream().filter(cti -> cti.getId().equals(sau.getCtiId())).findFirst();
                    if (ctiOptional.isPresent()) {
                        AssetCti cti = ctiOptional.get();
                        extra.put("ctiId", cti.getId());
                        extra.put("ctiName", cti.getName());
                        extra.put("cti", cti.getCode());
                        extra.put("ctiFullName", cti.getFullname());
                        extra.put("ctiFullCode", cti.getFullcode());
                        extra.put("assetType", cti.getAssetType());
                        extra.put("accountingMethod", cti.getAccountingMethod());
                    }
                    treeNode.setExtra(extra);
                    return treeNode;
                }).collect(Collectors.toList());
        return TreeUtil.build(collect, 0L);
    }

    @Override
    public IPage sauPage(Page page, QueryWrapper<AssetSau> query,AssetSau assetSau) {
        query.eq("t1.del_flag", 0);
        query.eq(StrUtil.isNotEmpty(assetSau.getCtiType()),"t1.CTI_TYPE",assetSau.getCtiType());
        query.likeRight(StrUtil.isNotEmpty(assetSau.getClassifiedCode()),"t1.CLASSIFIED_CODE",assetSau.getClassifiedCode());
        query.like(StrUtil.isNotEmpty(assetSau.getName()),"t1.NAME",assetSau.getName());
        query.eq(StrUtil.isNotEmpty(assetSau.getBarcode()),"t1.BARCODE",assetSau.getBarcode());
        query.like(StrUtil.isNotEmpty(assetSau.getModel()),"t1.MODEL",assetSau.getModel());
        query.like(StrUtil.isNotEmpty(assetSau.getUnit()),"t1.UNIT",assetSau.getUnit());
        BigDecimal b =  new BigDecimal(0);
        query.ge(assetSau.getAmount()!=null && assetSau.getAmount().compareTo(b) > 0,"AMOUNT",assetSau.getAmount());
        return this.baseMapper.sauPage(page, query);
    }

    @Override
    public SauPageVO getSauById(Long id) {
        AssetSau sau = this.getOne(Wrappers.<AssetSau>lambdaQuery().eq(AssetSau::getId, id));
        SauPageVO sauPageVO = new SauPageVO();
        BeanUtil.copyProperties(sau, sauPageVO);
        AssetCti cti = fyAssetCtiService.getOne(Wrappers.<AssetCti>query().lambda().eq(BaseEntity::getId, sau.getCtiId()));
        sauPageVO.setCtiId(cti.getId());
        sauPageVO.setCtiName(cti.getName());
        sauPageVO.setCtiCode(cti.getCode());
        sauPageVO.setCtiParentId(cti.getParentId());
        sauPageVO.setCtiParentName(cti.getParentName());
        sauPageVO.setCtiFullName(cti.getFullname());
        sauPageVO.setCtiFullCode(cti.getFullcode());
        sauPageVO.setAssetType(cti.getAssetType());
        sauPageVO.setAccountingMethod(cti.getAccountingMethod());
        return sauPageVO;
    }

    private void setFieldValue(AssetSau entity) {
        if (ObjectUtils.isNotEmpty(entity.getCtiId()) && entity.getCtiId() > 0) {
            AssetCti cti = fyAssetCtiService.getById(entity.getCtiId());
            entity.setClassified(cti.getFullname());
            entity.setClassifiedCode(cti.getFullcode());
            entity.setCtiType(cti.getAssetType());
        }
    }
}
